package com.glodon.paas.document.web.controller;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.glodon.paas.account.api.bean.User;
import com.glodon.paas.consts.StringConst;
import com.glodon.paas.document.api.bean.MemberView;
import com.glodon.paas.document.api.bean.Project;
import com.glodon.paas.document.api.bean.ProjectMember;
import com.glodon.paas.document.api.bean.ProjectMemberAttendees;
import com.glodon.paas.document.api.bean.StringUtil;
import com.glodon.paas.document.service.ProjectService;
import com.glodon.paas.document.service.util.WebService;
import com.glodon.paas.document.web.util.SecurityUtils;
import com.glodon.paas.exception.PaasServerExceptionFactory;
import com.glodon.paas.exception.i18n.ErrorCode;

/**
 *
 * 
 * @author xur
 */
@Controller
@RequestMapping("/project/member")
public class ProjectMemberController {

    public static final Logger LOGGER = LoggerFactory.getLogger(ProjectMemberController.class);
    @Autowired
    private ProjectService     projectService;
    @Autowired
    private WebService webService;
    @RequestMapping(value = "", method = RequestMethod.POST)
    @ResponseBody
    public MemberView invite(@RequestBody MemberView member, @RequestParam(value="reInvite",required=false)String reinvite,ModelMap model) throws IllegalAccessException,
                                                                            InvocationTargetException,
                                                                            NoSuchMethodException {
        if(reinvite==null){
            User owner = SecurityUtils.getCurrentUser();
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            StringBuffer url = request.getRequestURL();
            String basePath = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getContextPath()).toString();
            List<MemberView> resultList = projectService.inviteMembers(member, owner, basePath);
            // This will support multiple adding method in future
            // model.addAttribute(StringConst.ITEMS, resultList);
            return resultList.get(0);
            // model.putAll(BeanUtils.describe(memberView));
            // model.addAttribute(memberView);
        }
        return reInvite(member,model);
    }
    private MemberView reInvite(MemberView member, ModelMap model) {
        User owner = SecurityUtils.getCurrentUser();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        StringBuffer url = request.getRequestURL();
        String basePath = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getContextPath()).append("/project/member/acception").toString();
        ProjectMember pm = new ProjectMember();
        pm.setUserId(member.getAccount());
        pm.setProjectId(member.getProjectId());
        pm.setRoleId(pm.getRoleId());
        boolean result = projectService.reInvite(pm, owner, basePath);
        if (result) {
            member.setStatus(0);
           
        } else {
            member.setStatus(-1);
        }
        return member;
        
    }
    @RequestMapping(value = "", method = RequestMethod.GET)
    public void getMembers(@RequestParam(value="roleId",required=false) String roleId, @RequestParam("projectId") String projectId,
                           ModelMap model) {
        if(StringUtil.isBlank(roleId)){
            getProjectMembers(projectId,model);
        }else{
            List<MemberView> resultList = new ArrayList<MemberView>();
            resultList = projectService.showMembers(projectId, roleId, SecurityUtils.getCurrentUser().getId());
            model.addAttribute(StringConst.ITEMS, resultList); 
        }
        
    }
    private void getProjectMembers(String projectId, ModelMap model) {
        List<MemberView> resultList = new ArrayList<MemberView>();
        resultList = projectService.showProjectMembers(projectId,SecurityUtils.getCurrentUser().getId());
        model.addAttribute(StringConst.ITEMS, resultList);
    }
    @RequestMapping(value = "/acception", method = RequestMethod.GET)
    public void addMember(@RequestParam("userId") String userId, @RequestParam("token") String token, HttpServletRequest request, HttpServletResponse response) throws IOException {
        boolean result = projectService.confirmInvitation(userId, token);
        if (result) {
            
            ProjectMember member = projectService.getConfirmedMember(userId, token);
            if (member != null) {
                result = projectService.updateInvitationStatus(userId, token);
                if(result){
                    // add project id into this user project list
                    webService.addProjectRole(SecurityUtils.getCurrentUser().getId(),userId, member.getProjectId(),
                                                  member.getRoleId(),member.getGroupId());
                    Project project = projectService.getProject(SecurityUtils.getCurrentUser().getId(), member.getProjectId());
                    StringBuffer url = request.getRequestURL();
                    String basePath = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getContextPath()).append("/file/index#!myProject&id="+project.getFolderId()).toString();
                    response.sendRedirect(basePath);
                }
               
            } 
        } 

    }
    @RequestMapping(value = "/{memberId}", method = RequestMethod.DELETE)
    public void removeMember(@RequestParam("projectId") String projectId, @RequestParam("roleId") String roleId,@RequestParam(value="isOrg",required=false) String isOrg,
                             @PathVariable("memberId") String memberId, ModelMap model) {
        ProjectMember member =null;
        ProjectMemberAttendees attendees = projectService.getAttendeeById(memberId);
        boolean deletMember=false;
        if(attendees!=null){
            memberId = attendees.getMemberId();
            member = projectService.getMemberById(memberId);
            if(member==null)  throw PaasServerExceptionFactory.validateException("Invalid project member.",
                                                                                 new Exception("Invalid project member."));
            if(member.getIsOrg()!=1){
                deletMember = true;
            }
            if(attendees.getStatus()==0){
                projectService.setInvitaionInvalid(attendees.getInvitationId());
            }
        }else{
            member = projectService.getMemberById(memberId);
            if(member==null)  throw PaasServerExceptionFactory.validateException("Invalid project member.",
                                                                                 new Exception("Invalid project member."));
            if(member.getIsOrg()==1){
                deletMember = true;
            }
        }
        boolean result = false;
        if (member != null) {
            if (!projectId.equals(member.getProjectId()) || !roleId.equals(member.getRoleId())) {
                throw PaasServerExceptionFactory.validateException("Invalid project member.",
                                                                   new Exception("Invalid project member."));
            }
            result = projectService.removeMember(member.getId(),deletMember);
            if (result&&member.getStatus()==1) {
                result = webService.deleteProjectRole(SecurityUtils.getCurrentUser().getId(), member.getUserId(),
                                                          member.getProjectId(), member.getRoleId(),member.getGroupId());
            }
            if (result) {
                model.addAttribute(StringConst.RESULT, StringConst.SUCCESS);
            } else {
                model.addAttribute(StringConst.RESULT, StringConst.FAIL);
            }

        } else {
            throw PaasServerExceptionFactory.validateException("Member is not exist!",
                                                               new Exception("Member is not exist!")).setErrorCode(ErrorCode.MEMBER_NOT_EXIST);
        }

    }
    @RequestMapping(value = "", method = RequestMethod.PUT)
    public void updateRoleOfMember(@RequestParam("projectId") String projectId, @RequestParam("roleId") String roleId,
                                   @RequestBody MemberView memberForUpdate, ModelMap model) {
        boolean result = projectService.updateRoleOfMember(memberForUpdate.getId(), projectId,
                                                           roleId, memberForUpdate.getRoleId());
        if (result) {
            ProjectMember member = projectService.getMemberById(memberForUpdate.getId());
            model.addAttribute(StringConst.RESULT, StringConst.SUCCESS);
            model.addAttribute(StringConst.ITEMS, member);
        }
        model.addAttribute(StringConst.RESULT, StringConst.FAIL);
    }
    @RequestMapping(value = "/suggestion", method = RequestMethod.GET)
    public void getContactListAndOrg(ModelMap model) {
        List<Map<String, String>> resultList = projectService.showSuggestion(SecurityUtils.getCurrentUser().getId());
        model.addAttribute(StringConst.ITEMS, resultList);
    }
}